#include "month.h"

// see month.h
char Month::OUTPUT_FORMAT[] = "%2s %2s %2s %2s %2s %2s %2s";

// see month.h
Month::Month() {
    monthInYear = 0;
    numDays = 0;
    dates = NULL;
}

// see month.h
Month::~Month() {
    if (dates) { delete [] dates; }
}

// see month.h
void Month::setMonthInYear(int month, bool isLeapYear) {
    monthInYear = month;

    switch (month) {
        case 2:
            // Feb
            isLeapYear ? numDays = 29 : numDays = 28;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            // April, June, Sept, Nov
            numDays = 30;
            break;
        default:
            // Everything else
            numDays = 31;
            break;
    }
}

// see month.h
void Month::generateDates(int firstDay) {
    // If the dates already exist, delete them before re-creating them
    if (dates) { delete [] dates; }

    dates = new Date::Date[numDays];
    int tmpDay = firstDay;
    for (int i=0; i < numDays; i++) {
        dates[i].setDayInMonth(i+1);
        dates[i].setDayInWeek(tmpDay);
        if (tmpDay == 7) { tmpDay = 1; }
        else { tmpDay++; }
    }
}

// see month.h
int Month::getLastDay() {
    return dates[numDays - 1].getDayInWeek();
}

// see month.h
void Month::printMonth() {
    
    // My kingdom for static initialization instead of dynamic
    std::string* p = new std::string[7];
    for (int i=0; i<7; i++) {
        p[i] = "";
    }
    // Print the header
    std::cout << "\n\nSu Mo Tu We Th Fr Sa";
    
    // Iterate through the days in the month, assigning them to a position in p
    std::cout << "\n";
    std::stringstream ss;
    int day = 0;
    for (int i=0; i < this->numDays; i++) {
        // Get the day of the week, which corresponds to the position in p
        day = this->dates[i].getDayInWeek();
        
        // Get the actual day of the month, which is what we want to display
        ss << this->dates[i].getDayInMonth();
        p[day-1] = ss.str();
        
        // Reset the stream each time we write to ti
        ss.str("");
        ss.clear();
        
        // When day of the week is 7, write the entire line out
        if (day == 7) {
            // Write to the output buffer
            this->printDayLine(p);
        }
    }
    
    // If we ended on any day other than 7, we need to write the remainder.
    //   Wipe out the rest of the line, though.
    for (int i=day; i<7; i++) {
        p[i] = "";
    }
    this->printDayLine(p);

    delete [] p;
}

// see month.h
void Month::printDayLine(std::string* p) {
    char* buffer = new char[21];
    
    sprintf(buffer, Month::OUTPUT_FORMAT, 
        p[0].c_str(), p[1].c_str(), p[2].c_str(), 
        p[3].c_str(), p[4].c_str(), p[5].c_str(), 
        p[6].c_str());
    std::cout << buffer;
    std::cout << "\n";   
    
    delete buffer;
}